package Controleur;

import ilog.concert.IloException;
import Methodes.Methode;
import Methodes.Prob_Cplex;
import Methodes.Prob_Cvx;
import Methodes.Prob_Recuit;
import Methodes.Rec_Cplex;
import Methodes.Solution;
import DataIO.BinaireHydraulique;
import DataIO.BinaireThermique;
import DataIO.Data;
import DataIO.ReelleHydraulique;
import DataIO.ReelleThermique;

import Exception.ExceptionBadFileFormat;




/**
 * Classe de gestion des evenements entre la vue et le modéle (packages Reseau & Methode).
 * Un objet de cette classe contient toutes les données necessaire au problème.
 * @author ejouini
 *
 */
public class Controleur {

	/** Données necessaire au traitement. */
	private Data dataReel;
	private BinaireHydraulique dataBinaireHydro;
	private BinaireThermique dataBinaireTherm;
	private ReelleHydraulique dataReelHydro;
	private ReelleThermique dataReelTherm;
	private String cheminCVX;
	
	/** Objet Methode qui va correspondre a la methode de resolution choisie. */
	private Methode methode;
	
	/**
	 * Constructeur initialisant à NULL toutes nos classes de données.
	 */
	public Controleur() {
		dataReel = null;
		dataBinaireHydro = null;
		dataBinaireTherm = null;
		dataReelHydro = null;
		dataReelTherm = null;
		cheminCVX = "";
	}
	
	/**
	 * Methode qui appel la fonction de lecture de donnees en fonction du mode.
	 * @param fichier : fichier de donnees a analyser.
	 * @param mode : Recuit ou Recours.
	 * @throws ExceptionBadFileFormat
	 */
	public void lireDonnees(String fichier, String mode) throws ExceptionBadFileFormat {
		
		if ("Binaire" == mode) {
			dataReel = new Data(fichier);
			dataBinaireHydro = new BinaireHydraulique(fichier);
			dataBinaireTherm = new BinaireThermique(fichier);
		} else if ("CVX" == mode) {		
			cheminCVX = fichier;
		} else {
			dataReel = new Data(fichier);
			dataReelHydro = new ReelleHydraulique(fichier);
			dataReelTherm = new ReelleThermique(fichier);
		}
		
	}

	/**
	 * Méthode qui retourne une solution optimale du problème à l'aide de la
	 * méthode du recuit simulé.
	 * 
	 * @return Une solution optimale approchée du problème.
	 * @throws IloException 
	 */
	public Solution getSolutionParRecuit() throws IloException {
		System.out.println("recuit");
		methode = new Prob_Recuit(dataReel, dataBinaireTherm, dataBinaireHydro);
		methode.solve();
		return methode.getSolution();
		
	}


	/**
	 * Méthode qui retourne une solution optimale du probléme en le relaxant.
	 * 
	 * @return Une solution optimale approchée du probléme.
	 * @throws IloException 
	 */
	public Solution getSolutionParRelaxation() throws IloException {
		methode = new Prob_Cplex(dataReel, dataBinaireTherm, dataBinaireHydro, true);
		methode.solve();
		return methode.getSolution();	
	}

	/**
	 * M�thode qui retourne une solution optimale exacte du probleme a l'aide de cplex.
	 * 
	 * @return Une solution optimale exacte du probleme.
	 * @throws IloException 
	 */
	public Solution getSolutionExacte() throws IloException {
		methode = new Prob_Cplex(dataReel, dataBinaireTherm, dataBinaireHydro, false);
		methode.solve();
		return methode.getSolution();	
	}

	/**
	 * Méthode qui retourne une solution optimale du probleme par recours.
	 * 
	 * @return Une solution optimale approchee du probleme.
	 * @throws IloException 
	 */
	public Solution getSolutionParRecours() throws IloException {
		methode = new Rec_Cplex(dataReel, dataReelTherm, dataReelHydro);
		methode.solve();
		return methode.getSolution();
	}
	
	/**
	 * Méthode qui affiche la solution optimale du problème calculée par CVX.
	 * @return
	 * @throws IloException 
	 */
	public Solution getSolutionParCVX() throws IloException {
		methode = new Prob_Cvx(cheminCVX);
		methode.solve();
		return methode.getSolution();
	}
	
	/**
	 * Methode qui verifie si les donnees on correctement ete recuperees
	 * @param Recuit ou Recours
	 * @return vrai si ok, faut sinon.
	 */
	public boolean dataIsNotNull(String mode) {
		if ("Binaire" == mode) {
			return ((dataBinaireHydro != null) && (dataBinaireTherm != null));
		}else if ("CVX" == mode) {
			return (cheminCVX != "");
		}else {
			return ((dataReel != null) && (dataReelHydro != null) && (dataReelTherm != null));
		}
	}
	

	/**
	 * Methode qui reinitialise les donnees de recuit du probleme.
	 * 
	 */
	public void resetDataBinaire() {
		dataBinaireHydro = null;
		dataBinaireTherm = null;
	}
	
	/**
	 * Methode qui reinitialise les donnees de recours du probleme. 
	 */
	public void resetDataReel() {
		dataReel = null;
		dataReelHydro = null;
		dataReelTherm = null;
		
	}

	/**
	 * Methode qui reinitialise les donnees resultats de CVX.
	 */
	public void resetDataCVX() {
		cheminCVX = "";
	}

	
	
}
